﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows;
using System.ComponentModel;

namespace NLarge
{
    public class HotkeyTextBox : TextBox
    {
        public HotkeyTextBox() : base()
        {
            this.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(HotkeyTextBox_PreviewKeyDown);
            this.PreviewKeyUp += new System.Windows.Input.KeyEventHandler(HotkeyTextBox_PreviewKeyUp);
            this.TextChanged += new TextChangedEventHandler(HotkeyTextBox_TextChanged);
            this.AcceptsReturn = true;
            this.AcceptsTab = true;
        }


        void HotkeyTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            UpdateTextInBox();            
        }

        void HotkeyTextBox_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            UpdateTextInBox();
        }

        List<Key> ModifierKeyList = new List<Key>  
        {
            Key.LeftCtrl, Key.LeftAlt, Key.LeftShift, Key.RightCtrl, Key.RightAlt, Key.RightShift, Key.System, Key.LWin, Key.RWin
        };

        void HotkeyTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            //System.Diagnostics.Debug.WriteLine("HTB " + e.SystemKey + " " + e.Key);
            Key pressedKey = e.Key;
            if (pressedKey == Key.System)
            {
                pressedKey = e.SystemKey;
            }
            ModifierKeys = e.KeyboardDevice.Modifiers;
            if (!ModifierKeyList.Contains(pressedKey))
            {
                Key = pressedKey;
            }
            else
            {
                Key = Key.None;
            }

            e.Handled = true;
        }


        #region (ModifierKeys)ModifierKeys DependencyProperty

        [Category("Hotkey"), DisplayName("ModifierKeys"), Description("ModifierKeys")]
        public ModifierKeys ModifierKeys
        {
            get { return (ModifierKeys)GetValue(ModifierKeysProperty); }
            set { SetValue(ModifierKeysProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ModifierKeys.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ModifierKeysProperty =
            DependencyProperty.Register("ModifierKeys", typeof(ModifierKeys), typeof(HotkeyTextBox),
            new FrameworkPropertyMetadata(
              (ModifierKeys)ModifierKeys.None,
              new PropertyChangedCallback(OnModifierKeysChanged)
              ),
            new ValidateValueCallback(IsModifierKeysValid));

        private static void OnModifierKeysChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            HotkeyTextBox instance = sender as HotkeyTextBox;
            ModifierKeys newValue = (ModifierKeys)e.NewValue;
            if (instance != null)
            {
                instance.UpdateTextInBox();
            }
        }

        private static bool IsModifierKeysValid(object valueO)
        {
            ModifierKeys value = (ModifierKeys)valueO;
            // TODO: Return validation result for value.
            return true;
        }

        #endregion

        #region (Key)Key DependencyProperty

        [Category("Hotkey"), DisplayName("Key"), Description("Key")]
        public Key Key
        {
            get { return (Key)GetValue(KeyProperty); }
            set { SetValue(KeyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Key.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty KeyProperty =
            DependencyProperty.Register("Key", typeof(Key), typeof(HotkeyTextBox),
            new FrameworkPropertyMetadata(
              (Key)Key.None,
              new PropertyChangedCallback(OnKeyChanged)
              ),
            new ValidateValueCallback(IsKeyValid));

        private static void OnKeyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            HotkeyTextBox instance = sender as HotkeyTextBox;
            Key newValue = (Key)e.NewValue;
            if (instance != null)
            {
                instance.UpdateTextInBox();
            }
        }

        private static bool IsKeyValid(object valueO)
        {
            Key value = (Key)valueO;
            // TODO: Return validation result for value.
            return true;
        }

        #endregion

        private void UpdateTextInBox()
        {
            string keyString = Key.ToString();
            if (keyString.Length == 2 && keyString[0] == 'D' && Char.IsDigit(keyString[1]))
            {
                keyString = keyString[1].ToString();
            }

            string textinBox = ModifierKeys.ToString() + " + " + keyString;
            if (ModifierKeys == ModifierKeys.None) textinBox = keyString;
            if (Key == Key.None) textinBox = ModifierKeys.ToString();
            this.Text = textinBox;
        }



    }
}
